package com.minelx.woods.task.common;

import com.minelx.landisk.filesystem.core.File;

import java.io.IOException;
import java.util.List;

public class ProcessExecuteResult {
	private final String command;

	private final boolean isSuccess;

	private final String commonOutput;

	private final String errorOutput;

	private ProcessExecuteResult(String command, boolean isSuccess, String commonOutput, String errorOutput) {
		this.isSuccess = isSuccess;
		this.commonOutput = commonOutput;
		this.errorOutput = errorOutput;
		this.command = command;
	}

	public String getCommand() {
		return command;
	}

	public boolean isSuccess() {
		return isSuccess;
	}

	public String getCommonOutput() {
		return commonOutput;
	}

	public String getErrorOutput() {
		return errorOutput;
	}

	@Override
	public String toString() {
		return "ProcessExecuteResult{" +
				"command='" + command + '\'' +
				", isSuccess=" + isSuccess +
				", commonOutput='" + commonOutput + '\'' +
				", errorOutput='" + errorOutput + '\'' +
				'}';
	}

	void catchYourBack(List<File> backupFiles) {
		if (!isSuccess()) {
			try {
				for (File file : backupFiles) {
					TempFile.of("bak__" + file.path().getName()).file()
							.write(file.inputStream());
				}
			} catch (IOException e) {
				throw new RuntimeException("error while saving bak file.", e);
			}
			System.out.println("debug logs: " + getCommonOutput());
			throw new RuntimeException("error while executing command: " + command + ", error message is: " + getErrorOutput());
		}
	}

	private static Process runCommand(String command) {
		try {
			System.out.println("PandasHelper.runCommand ==> running command: " + command);
			return Runtime.getRuntime().exec(command);
		} catch (IOException e) {
			throw new RuntimeException("error while running command.", e);
		}
	}

	public static ProcessExecuteResult execute(String command) {
		try {
			Process process = runCommand(command);
			int exitCode = process.waitFor();
			return of(
					command,
					exitCode == 0,
					new String(process.getInputStream().readAllBytes()),
					new String(process.getErrorStream().readAllBytes()));
		} catch (InterruptedException | IOException e) {
			throw new RuntimeException("error while waiting for response from process.", e);
		}
	}

	public static ProcessExecuteResult of(String command, boolean isSuccess, String commonOutput, String errorOutput) {
		return new ProcessExecuteResult(command, isSuccess, commonOutput, errorOutput);
	}
}
